package com.bank.backend.boot.server.service.impl;


import cn.hutool.core.util.StrUtil;
import com.bank.backend.boot.base.constant.BaseConstant;
import com.bank.backend.boot.base.constant.ExceptionConstant;
import com.bank.backend.boot.base.enums.AccountEnum;
import com.bank.backend.boot.base.enums.BankOperationEnum;
import com.bank.backend.boot.base.model.dto.BankOperationDTO;
import com.bank.backend.boot.base.model.entity.Account;
import com.bank.backend.boot.base.model.entity.BankOperation;
import com.bank.backend.boot.base.model.entity.BankUser;
import com.bank.backend.boot.base.model.exception.GlobalException;
import com.bank.backend.boot.base.model.vo.BankOperationVO;
import com.bank.backend.boot.server.converter.BankOperationConverter;
import com.bank.backend.boot.server.mapper.AccountMapper;
import com.bank.backend.boot.server.mapper.BankOperationMapper;
import com.bank.backend.boot.server.mapper.BankUserMapper;
import com.bank.backend.boot.server.service.BankOperationService;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import jakarta.annotation.Resource;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;

/**
* @author JiaoWei
* @description 针对表【bank_operation(银行人员操作记录)】的数据库操作Service实现
* @createDate 2025-03-24 19:01:27
*/
@Service
public class BankOperationServiceImpl extends ServiceImpl<BankOperationMapper, BankOperation>
    implements BankOperationService {

    @Resource
    private BankOperationMapper bankOperationMapper;

    @Resource
    private BankOperationConverter bankOperationConverter;

    @Resource
    private BankUserMapper bankUserMapper;

    @Resource
    private AccountMapper accountMapper;

    @Override
    public Page<BankOperationVO> queryOperationPage(int current, int pageSize) {
        Page<BankOperation> page = new Page<>(current, pageSize);
        Page<BankOperation> bankOperationPage = bankOperationMapper.selectPage(page, null);
        if (null == bankOperationPage) {
            return null;
        }
        Page<BankOperationVO> bankOperationVOPage = new Page<>();
        List<BankOperationVO> bankOperationVOS = new ArrayList<>();
        for (BankOperation bankOperation : bankOperationPage.getRecords()) {
            BankOperationVO bankOperationVO = bankOperationConverter.converter(bankOperation);
            BankUser bankUser = bankUserMapper.selectById(bankOperation.getBuid());
            if (null == bankUser) {
                bankOperationVO.setBankNumber(BaseConstant.MACHINE_OPERATION);
            } else {
                bankOperationVO.setBankNumber(bankUser.getBankNumber());
            }
            Account account = accountMapper.selectById(bankOperation.getAid());
            if (null == account) {
                throw new GlobalException(ExceptionConstant.ACCOUNT_NOT_EXIST);
            } else {
                bankOperationVO.setAccountNumber(account.getAccountNumber());
            }
            bankOperationVOS.add(bankOperationVO);
        }
        bankOperationVOPage.setRecords(bankOperationVOS);
        bankOperationVOPage.setTotal(bankOperationPage.getTotal());
        bankOperationVOPage.setPages(bankOperationPage.getPages());
        bankOperationVOPage.setCurrent(bankOperationPage.getCurrent());
        bankOperationVOPage.setSize(bankOperationPage.getSize());
        return bankOperationVOPage;
    }

    @Override
    public boolean saveOperation(BankOperationDTO bankOperationDTO) {
        String bankNumber = bankOperationDTO.getBankNumber();
        if (StrUtil.isEmpty(bankNumber)) {
            throw new GlobalException(ExceptionConstant.BANK_NUMBER_NULL);
        }
        BankUser bankUser = bankUserMapper.getBankUserByBankNumber(bankNumber);
        if (null == bankUser) {
            throw new GlobalException(ExceptionConstant.USER_NOT_EXIST);
        }
        BankOperation bankOperation = bankOperationConverter.converter(bankOperationDTO);
        bankOperation.setBuid(bankUser.getId());
        bankOperation.setCreateTime(new Date());
        bankOperation.setUpdateTime(new Date());
        UpdateWrapper<Account> updateWrapper = new UpdateWrapper<>();
        updateWrapper.eq("id", bankOperationDTO.getAid());
        // 处理流程中
        if (bankOperationDTO.getResult() == BankOperationEnum.RESULT_0.getCode()) {
            bankOperation.setFinishTime(null);
            updateWrapper.set("state", AccountEnum.STATE_1.getCode());
        } else {
            // 处理生效的
            bankOperation.setFinishTime(new Date());
            updateWrapper.set("state", bankOperationDTO.getType());
        }
        int update = accountMapper.update(updateWrapper);
        if (update == 0) {
            throw new GlobalException(ExceptionConstant.UPDATE_ERROR);
        }
        QueryWrapper<BankOperation> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("aid", bankOperationDTO.getAid());
        BankOperation one = bankOperationMapper.selectOne(queryWrapper);
        int i = 0;
        if (null == one) {
            i = bankOperationMapper.insert(bankOperation);
        } else {
            i = bankOperationMapper.updateBankOperation(bankOperation, one.getId());
        }
        return i != 0;
    }

    @Override
    public boolean relieveOperation(Long id) {
        BankOperation bankOperation = bankOperationMapper.selectById(id);
        if (null == bankOperation) {
            throw new GlobalException(ExceptionConstant.BANK_OPERATION_NOT_EXIST);
        }

        UpdateWrapper<Account> updateWrapper = new UpdateWrapper<>();
        updateWrapper.eq("id", bankOperation.getAid())
                    .set("state", AccountEnum.STATE_0.getCode());
        int update = accountMapper.update(updateWrapper);
        if (update == 0) {
            throw new GlobalException(ExceptionConstant.UPDATE_ERROR);
        }

        bankOperation.setDescription(BaseConstant.ACCOUNT_RELIEVE_FINISH);
        bankOperation.setResult(BankOperationEnum.RESULT_2.getCode());
        bankOperation.setFinishTime(new Date());
        bankOperation.setUpdateTime(new Date());
        int i = bankOperationMapper.updateById(bankOperation);
        return true;
    }
}




